<template>
    <component :is="as" class="numberScroll" :class="{ 'border-animate': showAnimate }"
        :style="{ '--i': i, '--delay': delay, '--color': color, '--width': width, }" @animationend="showAnimate = false">
        <ul ref="ul" :class="{ animate: showAnimate }">
            <li>0</li>
            <li>1</li>
            <li>2</li>
            <li>3</li>
            <li>4</li>
            <li>5</li>
            <li>6</li>
            <li>7</li>
            <li>8</li>
            <li>9</li>
            <li>0</li>
        </ul>

        <svg width="0" height="0">
            <!-- filter元素作用是作为原子滤镜操作的容器 -->
            <filter id="blur">
                <!-- 该滤镜对输入图像进行高斯模糊 -->
                <!-- 其中 in="SourceGraphic" 属性指明了模糊效果要应用于整个图片，stdDeviation 属性定义了模糊的程度 -->
                <feGaussianBlur in="SourceGraphic" :stdDeviation="`0 ${blur}`" />
            </filter>
        </svg>
    </component>
</template>

<script setup lang="ts">
import { ref, watch, onMounted } from "vue";
const props = defineProps({
    // 该组件可以作为什么标签使用
    as: {
        type: String,
        default: "div",
    },
    // css变量 单数字
    i: {
        type: Number,
        default: 0,
        // 验证函数
        validator: (v: Number) => v < 10 && v >= 0 && Number.isInteger(v)
    },
    // css变量 延时
    delay: {
        type: Number,
        default: 0
    },
    // css变量 模糊的程度
    blur: {
        type: Number,
        default: 2
    },
    // css变量 颜色
    color: {
        type: String,
        default: "#ffffff"
    },
    // css变量 宽度
    width: {
        type: String,
        default: "20px"
    },
});

// 是否显示动画
const showAnimate = ref(true);
// 延时器
const timer = ref(0);

// 获取ul元素
// 定义html接口
interface HtmlAttr {
    [propName: string]: any,
}
const ul: HtmlAttr = ref(null)

watch(() => [props.i], () => {
    showAnimate.value = true;
}, { deep: true, immediate: false });

onMounted(() => {
    // 获取设备类型
    const ua: string = navigator.userAgent.toLowerCase()
    const testUA = (regexp: RegExp) => regexp.test(ua)
    // 是否是Safari
    const isSafari: boolean = testUA(/safari/g) && !testUA(/chrome/g);

    // Safari浏览器的兼容代码
    isSafari && (timer.value = window.setTimeout(() => {
        ul.value.setAttribute('style', `
        animation: none;
        transform: translateY(calc(var(--i) * -9.09%))
      `)
    }, props.delay * 1000))
})

</script>

<style lang="less" scoped>
.numberScroll {
    width: var(--width, 20px);
    height: calc(var(--width, 20px) * 1.8);
    color: var(--color, #fff);
    font-size: calc(var(--width, 20px) * 1.7);
    line-height: calc(var(--width, 20px) * 1.8);
    text-align: center;
    overflow: hidden;
    font-weight: 900;
}

.animate {
    animation: move .3s linear infinite, bounce-in-down 1s calc(var(--delay) * 1s) forwards
}

.border-animate {
    animation: enhance-bounce-in-down 0.3s calc(var(--delay) * 1s) forwards
}

ul {
    padding: 0;
    margin: 0;
    list-style: none;
    transform: translateY(calc(var(--i) * -9.09%));
}

@keyframes move {
    from {
        transform: translateY(-90%);
        filter: url(#blur)
    }

    to {
        transform: translateY(1%);
        filter: url(#blur)
    }
}

@keyframes bounce-in-down {
    from {
        transform: translateY(calc(var(--i) * -9.09% - 7%));
        filter: none
    }

    25% {
        transform: translateY(calc(var(--i) * -9.09% + 3%))
    }

    50% {
        transform: translateY(calc(var(--i) * -9.09% - 1%))
    }

    70% {
        transform: translateY(calc(var(--i) * -9.09% + .6%))
    }

    85% {
        transform: translateY(calc(var(--i) * -9.09% - .3%))
    }

    to {
        transform: translateY(calc(var(--i) * -9.09%))
    }
}

@keyframes enhance-bounce-in-down {
    25% {
        transform: translateY(8%)
    }

    50% {
        transform: translateY(-4%)
    }

    70% {
        transform: translateY(2%)
    }

    85% {
        transform: translateY(-1%)
    }

    to {
        transform: translateY(0)
    }
}
</style>